package com.demo2;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-12-21
 * Time: 20:48
 */
//基于循环队列实现的
class MyBlockQueue{
    public int[] elem = new int[10000];
    //头指针
    public int first;
    //尾指针
    public int tail;
    //有效数据个数
    public int size;

    //使用wait 和 notify 实现阻塞和唤醒 new一个锁对象
    Object locker = new Object();

    //入队列
    public void put(Integer val) throws InterruptedException {
        //wait和notify一定要配合者synchronized使用 不然直接报错
        synchronized (locker){
            //判断满不满
            if (size == elem.length){
                //阻塞到有元素出队列了来唤醒
                locker.wait();
            }
            elem[tail] = val;
            tail++;
            if (tail >= elem.length){
                tail = 0;
            }
            size++;
            locker.notify();
        }
    }

    //出队列
    public Integer take() throws InterruptedException {
        synchronized (locker){
            //判断空不空
            if (size == 0){
                //阻塞到元素入队列了来唤醒
                locker.wait();
            }
            int ret = elem[first];
            //出队列也是++
            first++;
            if (first>=elem.length){
                first = 0;
            }
            size--;
            locker.notify();
            return ret;
        }
    }

}


//阻塞队列
public class TestDemo2 {
    private static MyBlockQueue queue = new MyBlockQueue();

    public static void main(String[] args) {
        //基于以上的阻塞队列 可以衍生出生产者 消费者模型
        Thread producer = new Thread(()->{
            int num = 0;
            while (true){
                System.out.println("生产了:"+ num);
                try {
                    queue.put(num);
                    num++;
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();

        Thread consumer = new Thread(()->{
            while (true){
                try {
                    int num = queue.take();
                    System.out.println("消费了: " + num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        consumer.start();
    }
}
